package src.ee.ioc.smaug.parser;

import java.io.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import src.ee.ioc.smaug.fsm.*;
import src.ee.ioc.smaug.world.evolution.*;


public class ParametersParser extends DefaultHandler {

 
    public static final EntityResolver ENTITY_RESOLVER = new EntityResolver() {

        public InputSource resolveEntity(String publicId, String systemId) {
            if (systemId != null && systemId.endsWith("dtd")) {
                return new InputSource(EnvDescription.fsmdtd);
            }
            return null;
        }

    };

    private class ParametersHandler extends DefaultHandler {
        /*
         * Constants for package file format tokens
         */

        private static final String EL_PARAMETER = "parameter";

        private static final String ATR_PARAMETER_NAME = "name";

       
        private static final String VAL_MUTATIONAPROBABILITY = "mutationProb";
        private static final String VAL_FFTYPE = "FFtype";
        private static final String VAL_MUTTYPE = "MUTtype";
        private static final String VAL_CROSSTYPE = "CROSStype";
        private static final String VAL_SELTYPE = "SELtype";
        private static final String VAL_DATAFILE = "dataFile";
        private static final String VAL_FSMXMLFILENAME = "FSMXMLfilename";
        private static final String VAL_PARAMXMLFILENAME = "ParamXMLfilename";
        private static final String VAL_LOGFILENAME = "LOGfilename";
        private static final String VAL_LOGLEVEL = "loglevel";
        private static final String VAL_NUMBEROFSTATES = "numberOfStates";
        private static final String VAL_GENERATING = "generating";
        private static final String VAL_BEINGTYPE= "beingType";
        private static final String VAL_NUMBEROFGENERATIONS= "numberOfGenerations";
        private static final String VAL_SIZEOFPOPULATION= "sizeOfPopulation";
        
        
        private static final String ATR_PARAMETER_PVALUE = "pvalue";
        
        private static final String VAL_MOORE_MACHINE_FIXED = "MOORE_MACHINE_FIXED";
        private static final String VAL_MEALY_MACHINE_FIXED = "MEALY_MACHINE_FIXED";
        private static final String VAL_MOORE_MACHINE_MAX = "MOORE_MACHINE_MAX";
        
        private static final String VAL_ONE_POINT_CROSSOVER = "ONE_POINT_CROSSOVER";
        private static final String VAL_TWO_POINT_CROSSOVER= "TWO_POINT_CROSSOVER";
        
        private static final String VAL_MUTATION= "MUTATION";
        private static final String VAL_INVERSION= "INVERSION";
        
        private static final String VAL_HAMMING_DISTANCE= "HAMMING_DISTANCE";
        private static final String VAL_MAX_PREFIX= "MAX_PREFIX";
        
        private static final String VAL_GENERATING_BIN= "GENERATING_BIN";
        private static final String VAL_GENERATING_DEC= "GENERATING_DEC";
        
        private StringBuilder charBuf;

        private String element;

        ParametersHandler() {
            super();
        }

        @Override
        public void startDocument() {
            if (charBuf == null)
                charBuf = new StringBuilder();
        }

        @Override
        public InputSource resolveEntity(String publicId, String systemId)
                throws IOException, SAXException {

            return ENTITY_RESOLVER.resolveEntity(publicId, systemId);
        }

        @Override
        public void error(SAXParseException spe) {
            // Error generated by the parser
        }

        @Override
        public void warning(SAXParseException e) {
        }

        @Override
        public void setDocumentLocator(Locator l) { // Save this to resolve
            // relative URIs or to give
            // diagnostics.
        }

        @Override
        public void startElement(String namespaceURI, String lName,
                String qName, Attributes attrs) {
            element = qName;
            if (element.equals(EL_PARAMETER)) {
                String name = attrs.getValue(ATR_PARAMETER_NAME);
                
                if (name != null && name.equals(VAL_MUTATIONAPROBABILITY)) {
                   String value = attrs.getValue(ATR_PARAMETER_PVALUE);
                   EnvDescription.mutationProb=Double.parseDouble(value);
                }
                else if (name != null && name.equals(VAL_FFTYPE)) {
                    String value = attrs.getValue(ATR_PARAMETER_PVALUE);
                    EnvDescription.mutationProb=Double.valueOf(value);
                 }
            } 

        }

        @Override
        public void endElement(String namespaceURI, String sName, String qName) {
             if (qName.equals(EL_PARAMETER)) {
             
            } 
        }

        @Override
        public void characters(char[] buf, int offset, int len) {
            // Characters may be delivered in multiple chunks so we just
            // accumulate them here.
            charBuf.append(buf, offset, len);
        }

    }

    private ParametersParser(File file) {

        // Use an instance of ourselves as the SAX event handler
        DefaultHandler handler = new ParametersHandler();

        // Use the validating parser
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // factory.setFeature("http://xml.org/sax/features/validation", true);
        factory.setValidating(true);

        try {
            // Parse the input
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse(file, handler);
            // factory.setFeature("http://xml.org/sax/features/validation",
            // true);
            factory.setValidating(true);
        } catch (SAXException sxe) {
            // Error generated by this application (or a parser-initialization
            // error)
            System.err
                    .println("Error generated by this application (or a parser-initialization error)");
        } catch (ParserConfigurationException pce) {
            // Parser with specified options can't be built
            System.err.println("Parser with specified options can't be built");

        } catch (IOException ioe) {
            // I/O error
            System.err.println("I/O error");
        }

    }


}
